package cn.bluech.lib.ui.widget;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Scroller;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import com.bumptech.glide.request.RequestOptions;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import cn.bluech.lib.R;


public class BannerView extends FrameLayout implements ViewPager.OnPageChangeListener {
    private static final int POLL_DELAY_MS = 4000;
    private Context context;
    private ViewPager contentVp;
    private LinearLayout indicatorsLy;
    private TextView titleTv;
    private TextView descriptionTv;

    private MyPagerAdapter adapter;
    private List<ItemInfo> imgs = new ArrayList<>();
    private int prePosition = 0;
    private AutoRollRunnable autoRollRunnable;
    private Listener listener;

    public BannerView(@NonNull Context context) {
        this(context, null);
    }

    public BannerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BannerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        autoRollRunnable = new AutoRollRunnable();
        initViews();
    }

    private void initViews() {
        View.inflate(context, R.layout.view_banner, this);
        contentVp = (ViewPager) findViewById(R.id.vp_view_content);
        indicatorsLy = (LinearLayout) findViewById(R.id.ly_view_indicators);
        titleTv = findViewById(R.id.tv_view_title);
        descriptionTv = findViewById(R.id.tv_view_description);

        adapter = new MyPagerAdapter();
        contentVp.setAdapter(adapter);
        contentVp.addOnPageChangeListener(this);

        // 设置滚动时间
        ViewPagerScroller pagerScroller = new ViewPagerScroller(context);
        pagerScroller.setScrollDuration(1000);//设置时间，时间越长，速度越慢
        pagerScroller.initViewPagerScroll(contentVp);
    }

    private int dp2px(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
    }

    public void setImgs(List<ItemInfo> imgs) {
        this.imgs = imgs;
        indicatorsLy.removeAllViews();
        if ((null == imgs) || (imgs.size() == 0)) {
            titleTv.setText("");
            descriptionTv.setText("");
            return;
        }
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(dp2px(3), dp2px(3));
        params.setMargins(dp2px(2), 0, dp2px(2), 0);
        for (ItemInfo img : imgs) {
            View view = new View(context);
            view.setLayoutParams(params);
            view.setBackgroundResource(R.drawable.selector_banner_indicator);
            indicatorsLy.addView(view);
        }
        // 设置起始位置在Integer.MAX_VALUE中间，并且以imgs.size()对齐
        //contentVp.setCurrentItem((Integer.MAX_VALUE/2/imgs.size())*imgs.size());
        indicatorsLy.getChildAt(0).setSelected(true);
        prePosition = 0;

        ItemInfo info = imgs.get(0);
        titleTv.setText(info.getTitle());
        descriptionTv.setText(info.getDescription());

        adapter.notifyDataSetChanged();
    }

    //开始轮播
    public void startRoll() {
        autoRollRunnable.start();
    }

    // 停止轮播
    public void stopRoll() {
        autoRollRunnable.stop();
    }


    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
        if (null == imgs)
            return;
        indicatorsLy.getChildAt(prePosition).setSelected(false);
        indicatorsLy.getChildAt(position % imgs.size()).setSelected(true);
        prePosition = position % imgs.size();

        ItemInfo info = imgs.get(position % imgs.size());
        titleTv.setText(info.getTitle());
        descriptionTv.setText(info.getDescription());

        // todo: 当滑动到最后一张的时候应当跳回到中间位置，当然，这几乎是不可能的
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

    private class MyPagerAdapter extends PagerAdapter {
        private List<ImageView> imgCache = new ArrayList<ImageView>();

        @Override
        public int getCount() {
            //return Integer.MAX_VALUE;
            return null == imgs ? 0 : imgs.size();
        }

        @Override
        public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
            return view == object;
        }

        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup container, final int position) {
            ImageView iv;

            //获取ImageView对象
            if (imgCache.size() > 0) {
                iv = imgCache.remove(0);
            } else {
                iv = new ImageView(context);
                iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
            }
            iv.setClickable(true);

            iv.setOnTouchListener(new OnTouchListener() {
                private int downX = 0;
                private long downTime = 0;

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            autoRollRunnable.stop();
                            //获取按下的x坐标
                            downX = (int) v.getX();
                            downTime = System.currentTimeMillis();
                            break;
                        case MotionEvent.ACTION_UP:
                            autoRollRunnable.start();
                            int moveX = (int) v.getX();
                            long moveTime = System.currentTimeMillis();
                            if (downX == moveX && (moveTime - downTime < 500)) {//点击的条件
                                //轮播图回调点击事件
                                //headerViewClickListener.HeaderViewClick(position % mUrlList.size());
                            }
                            break;
                        case MotionEvent.ACTION_CANCEL:
                            autoRollRunnable.start();
                            break;
                    }
                    return false;
                }
            });
            if ((null != imgs) && (imgs.size() > 0)) {
                //加载图片
                Glide.with(context)
                        .load(imgs.get(position % imgs.size()).getLogo())
                        .apply(new RequestOptions().centerCrop().placeholder(R.drawable.img_banner_def))
                        .transition(new DrawableTransitionOptions().crossFade())
                        .into(iv);
            }
            container.addView(iv);
            iv.setOnClickListener(v -> {
                if (listener != null) {
                    listener.onClicked(position);
                }
            });
            return iv;
        }

        @Override
        public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
            if (object instanceof ImageView) {
                ImageView iv = (ImageView) object;
                container.removeView(iv);
                imgCache.add(iv);
            }
        }
    }

    private class AutoRollRunnable implements Runnable {
        private Handler handler = new Handler(Looper.getMainLooper());
        //是否在轮播的标志
        boolean isRunning = false;
        int i = 0;

        public void start() {
            if (!isRunning) {
                isRunning = true;
                handler.removeCallbacks(this);
                handler.postDelayed(this, POLL_DELAY_MS);
            }
        }

        public void stop() {
            if (isRunning) {
                handler.removeCallbacks(this);
                isRunning = false;
            }
        }

        @Override
        public void run() {
            if (isRunning) {
                if (imgs.size() < 2) {
                    return;
                }
                i++;
                contentVp.setCurrentItem(i % imgs.size());
                handler.postDelayed(this, POLL_DELAY_MS);
            }
        }
    }

    private static class ViewPagerScroller extends Scroller {

        private int mScrollDuration = 2000; // 滑动速度

        /**
         * 设置速度速度
         *
         * @param duration
         */
        public void setScrollDuration(int duration) {
            this.mScrollDuration = duration;
        }

        public ViewPagerScroller(Context context) {
            super(context);
        }

        public ViewPagerScroller(Context context, Interpolator interpolator) {
            super(context, interpolator);
        }

        public ViewPagerScroller(Context context, Interpolator interpolator,
                                 boolean flywheel) {
            super(context, interpolator, flywheel);
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            super.startScroll(startX, startY, dx, dy, mScrollDuration);
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy) {
            super.startScroll(startX, startY, dx, dy, mScrollDuration);
        }

        public void initViewPagerScroll(ViewPager viewPager) {
            try {
                Field mScroller = ViewPager.class.getDeclaredField("mScroller");
                mScroller.setAccessible(true);
                mScroller.set(viewPager, this);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public Listener getListener() {
        return listener;
    }

    public void setListener(Listener listener) {
        this.listener = listener;
    }

    public interface Listener {
        void onClicked(int index);
    }

    public static class ItemInfo{
        private String title = "";
        private String logo = ""; // 图片地址
        private String description = "";

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getLogo() {
            return logo;
        }

        public void setLogo(String logo) {
            this.logo = logo;
        }
        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

    }
}
